home *** CD-ROM | disk | FTP | other *** search
- /*
- * minimal shell for memory hogs on the atariST
- * - gcc, MWC, or Alcyon C
- *
- * to configure:
- * edit config.h
- *
- * to compile:
- * see file README
- *
- * Builtins:
- * rm <list of files>
- * cp <src> <dst> both <src> <dest> must be files
- * WARNING: no checks for <src> <dst> being the same
- * ls {<regular exp>} with no arg ls *.*
- * cd {<dir>} with no arg cd $HOME
- * md <dir>
- * rd <dir>
- * pwd print working (current) directory
- * lo logout
- * @ file read commands from file, then revert back to stdin.
- * NO nested @'s allowed.
- *
- * Aliases, Path, Environment:
- * see config.h
- *
- * ++jrb bammi@dsrgsun.ces.cwru.edu
- */
-
- #include <osbind.h>
-
- #ifdef NULL
- #undef NULL
- #endif
-
- #define NULL 0L /* avoid stdio like the plague */
- #define BSIZE 256 /* size of all purpose buffer */
-
- #define PROMPT Bconws("# ")
- #define PRINTI(i) printi((int)i)
- #define CRLF Bconws(_crlf)
- #define REG /* register */
-
- typedef struct
- {
- char st_sp1[21]; /* Junk */
- char st_mode; /* File attributes */
- short st_time; /* Mod Time */
- short st_date; /* Mod date */
- long st_size; /* File size */
- char st_name[14]; /* File name */
- } STAT;
-
- #ifdef MWC
- long _stksize = 128; /* don't trim this any further!! */
- #else
- #ifdef __GNUC__
- long _stksize = 192; /* don't trim this any further!! */
- /* gcc needs extra due to inlines */
- #else /* alcyon */
- long _STKSIZ = 128; /* don't trim this any further!! */
- #endif
- #endif
-
- char *_crlf = "\r\n";
- int rhandle = -10; /* some val < -5 */
- char buf[BSIZE];
- STAT *stat;
-
- #include "config.h" /* all the user configurable stuff in there */
-
- #ifdef __GNUC__
- #include <stddef.h>
- void Bconws(char *);
- void printi(int);
- char *nextarg(char **);
- char *alltolower(char *);
- int cd(char *);
- int ls(char *);
- void putls(STAT *, int);
- int rm(char *);
- int cp(char *);
- int md(char *);
- int rd(char *);
- int lo(void);
- int at(char *);
- int pwd(void);
- void read_at(char *);
- int find_builtin(char *);
- int find_alias(char *);
- char *existf(char *, char *, char *);
- char *find_ext(char *);
- int do_command(char *, char *, char *);
- int main(void);
- extern char *strcpy(char *, char *);
- extern char *strcat(char *, char *);
- extern char *index(char *, int);
- extern size_t strlen(char *);
-
- #else
-
- int ls(), rm(), cp(), cd(), md(), rd(), lo(), at(), pwd();
- extern char *strcpy();
- extern char *strcat();
- extern char *index();
- extern int strlen();
-
- #endif
-
- /*
- * Builtin commands
- *
- */
- typedef struct {
- char *command; /* command string */
- int (*routine)(); /* routine to invoke */
- } BUILTIN;
-
- BUILTIN builtin[] = {
- { "rm", rm },
- { "cp", cp },
- { "ls", ls },
- { "cd", cd },
- { "md", md },
- { "rd", rd },
- { "lo", lo },
- { "@", at },
- { "pwd", pwd },
- { (char *)NULL, (int (*)())NULL }
- };
-
-
- void Bconws(s)
- REG char *s;
- {
- while(*s) Bconout(2, *s++);
- }
-
- void printi(val)
- REG int val;
- {
- static int divisors[] = { 10000, 1000, 100, 10, 1 };
- register int first = 0, div_idx = 0;
- register int j;
-
- /* Special Cases */
- if (val == 0)
- {
- Bconout(2, '0');
- }
- else if (val == -32768)
- {
- Bconws("-32768");
- }
- else
- {
- /* Get digit for each power of 10 and print them, skip leading 0's */
- if (val < 0)
- {
- Bconout(2, '-');
- val = -val;
- }
-
- while( div_idx < 5 )
- {
- if(((j = val / divisors[div_idx]) != 0) || first != 0)
- {
- Bconout(2, j + '0');
- first = 1;
- }
- val %= divisors[div_idx++];
- }
- }
- }
-
- #define iswhite(c) ((c == ' ') || (c == '\t'))
-
- /*
- * return pointer to next arg, and advance q to char following next arg
- */
- char *nextarg(q)
- REG char **q;
- {
- register char *s = *q;
- register char *p;
-
- if(*s == '\0')
- return (char *)NULL;
- while(iswhite(*s)) s++;
- p = s; s++;
- while((!iswhite(*s)) && (*s != '\0')) s++;
- if(*s != '\0')
- {
- *s = '\0';
- *q = ++s;
- }
- else
- *q = s;
-
- return p;
- }
-
-
- #define isupper(c) ((c >= 'A') && (c <= 'Z'))
- #define tolower(c) (c - 'A' + 'a')
-
- char *alltolower(s)
- REG char *s;
- {
- register char *p = s;
-
- while(*p != '\0')
- {
- if(isupper(*p)) *p = tolower(*p);
- p++;
- }
- return s;
- }
-
- int cd(s)
- REG char *s;
- {
- register char *d, *path;
- register int drive;
-
- if(*s == '\0')
- return cd(HOME);
-
- if((d = index(s,':')) == (char *)NULL)
- {
- /* Drive was not specified, must mean the current drive */
- path = s;
- }
- else
- {
- d--;
- if(isupper(*d))
- {
- *d = tolower(*d);
- }
- drive = *d - 'a';
- if(d[2] != '\\') /* just gave D: */
- {
- /* we will shove in the '\' */
- d[1] = '\\';
- path = &d[1];
- }
- else
- path = &d[2];
-
- /* Set the Drive */
- if(Dsetdrv(drive) < 0)
- {
- Bconws("?drv: "); Bconout(2, *d); CRLF;
- return 2;
- }
-
- }
-
- /* Set the Path */
- if(Dsetpath(path) != 0)
- {
- Bconws("?dir: "); Bconws(path); CRLF;
- return 3;
- }
- return 0;
- }
-
- int pwd()
- {
- char path[32];
- extern char *alltolower();
-
- Bconout(2, (int)(Dgetdrv() + 'a'));
- Bconout(2, ':');
- Dgetpath(path, 0);
- if(*path == '\0')
- {
- path[0] = '\\';
- path[1] = '\0';
- }
- Bconws(alltolower(path)); CRLF;
- return 0;
- }
-
- #define HASWILD(S) \
- ((index(S, '*') != (char *)NULL) || (index(S, '?') != (char *)NULL))
-
- void putls(statbuf, count)
- REG STAT *statbuf;
- REG int count;
- {
- register int len = strlen(statbuf->st_name);
- extern char *alltolower();
-
- if((statbuf->st_mode) & 0x0010)
- {
- /* subtree */
- Bconws(alltolower(statbuf->st_name));
- Bconout(2, '/');
- len++;
- }
- else
- /* file */
- Bconws(alltolower(statbuf->st_name));
-
- if((count & 3) == 3)
- CRLF;
- else
- {
- len = 14 - len;
- while(len--)
- Bconout(2, ' ');
- }
- }
-
- int ls(s)
- REG char *s;
- {
- register int count;
-
- if(*s == '\0')
- return ls("*.*");
-
- if(HASWILD(s))
- (void) strcpy(buf, s);
- else
- {
- if(s[(strlen(s) - 1)] != '\\')
- {
- (void) strcpy(buf, s);
- (void) strcat(buf, "\\");
- }
- else
- (void) strcpy(buf, s);
- (void) strcat(buf, "*.*");
- }
- if(Fsfirst(buf, 0x0020 | 0x0010) != 0)
- {
- Bconws("?match: "); Bconws(buf); CRLF;
- return 1;
- }
-
- count = 0;
- if(!((strcmp(stat->st_name,".") == 0) ||
- (strcmp(stat->st_name, "..") == 0)))
- putls(stat, count++);
-
- while(Fsnext() == 0)
- {
- if(!((strcmp(stat->st_name,".") == 0) ||
- (strcmp(stat->st_name, "..") == 0)))
- putls(stat, count++);
- }
-
- if(count & 3)
- CRLF;
-
- return 0;
- }
-
- int rm(s)
- char *s;
- {
- register char *p;
- register int status = 0;
- extern char *nextarg();
-
- while((p = nextarg(&s)) != (char *)NULL)
- {
- if(Fdelete(p) != 0)
- {
- Bconws("?file: "); Bconws(s); CRLF;
- status = 1;
- }
- }
- return status;
- }
-
- int cp(s)
- char *s;
- {
- register char *p;
- register int src, dst;
- register long l, k;
- extern char *nextarg();
-
- if((p = nextarg(&s)) == (char *)NULL)
- {
- Bconws("?cp src dst"); CRLF;
- return 1;
- }
- if((src = Fopen(p, 0)) < (-3))
- {
- Bconws("?src: "); Bconws(p); CRLF;
- return src;
- }
- if((p = nextarg(&s)) == (char *)NULL)
- {
- Bconws("?cp src dst"); CRLF;
- k = 2;
- goto rmfin1;
- }
- if((dst = Fcreate(p, 0)) < (-3))
- {
- if((dst = Fopen(p, 1)) < (-3))
- {
- Bconws("?dst: "); Bconws(p); CRLF;
- k = dst;
- goto rmfin1;
- }
- }
- while( (l = Fread(src, (long)BSIZE, buf)) > 0L)
- {
- if((k = Fwrite(dst, l, buf)) != l)
- {
- Bconws("?Write Fail\r\n");
- goto rmfin;
- }
- }
- k = 0;
- rmfin:
- Fclose(dst);
- rmfin1:
- Fclose(src);
-
- return k;
- }
-
- int md(s)
- char *s;
- {
- extern char *nextarg();
- register char *p;
-
- if((p = nextarg(&s)) == (char *)NULL)
- {
- Bconws("?md\r\n");
- return 1;
- }
- return(Dcreate(p));
- }
-
- int rd(s)
- char *s;
- {
- extern char *nextarg();
- register char *p;
-
- if((p = nextarg(&s)) == (char *)NULL)
- {
- Bconws("?rd\r\n");
- return 1;
- }
- return(Ddelete(p));
- }
-
- int lo()
- {
- Pterm(0);
- }
-
- int at(s)
- REG char *s;
- {
- if((s == (char *)NULL) || (*s == '\0')) /* dependency !! */
- {
- if(rhandle > (-3))
- {
- Fclose(rhandle);
- rhandle = -10;
- }
- return 0;
- }
-
- if((rhandle = Fopen(s, 0)) < (-3))
- {
- Bconws("?file: "); Bconws(s); CRLF;
- return 1;
- }
- return 0;
- }
-
- void read_at(buf)
- char *buf;
- {
- char c;
- register char *p;
-
- p = &buf[2];
- buf[1] = 0;
- while(Fread(rhandle, 1L, &c) == 1L)
- {
- Bconout(2, c);
- if(c == '\r')
- {
- Bconout(2, '\n');
- *p = '\0';
- buf[1] = strlen(&buf[2]);
- Fread(rhandle, 1L, &c);
- return;
- }
- *p++ = c;
- }
- Fclose(rhandle);
- rhandle = -10;
- CRLF;
- }
-
-
- int find_builtin(s)
- REG char *s;
- {
- register int i;
- for(i = 0; builtin[i].command != (char *)NULL; i++)
- if(strcmp(s, builtin[i].command) == 0)
- return i;
- return -1;
- }
-
- int find_alias(s)
- REG char *s;
- {
- register int i;
- for(i = 0; alias[i].aname != (char *)NULL; i++)
- if(strcmp(s, alias[i].aname) == 0)
- return i;
- return -1;
- }
-
- char *existf(name, pth, ex)
- REG char *name, *pth, *ex;
- {
- register char *b = &buf[(BSIZE/2)];
-
- if(*pth != '\0')
- {
- (void) strcpy(b, pth);
- (void) strcat(b, name);
- }
- else
- (void) strcpy(b, name);
- if(*ex != '\0')
- (void) strcat(b, ex);
- if(Fsfirst(b, 0) == 0)
- return b;
- return (char *)NULL;
- }
-
-
- char *find_ext(s)
- REG char *s;
- {
- register char *p;
- register int i, j;
- extern char *existf();
-
- for(i = 0; path[i] != (char *)NULL; i++)
- for(j = 0; ext[j] != (char *)NULL; j++)
- if(( p = existf(s, path[i], ext[j])) != (char *)NULL)
- return p;
- return (char *)NULL;
- }
-
- int do_command(com, optarg, args)
- char *com, *optarg, *args;
- {
-
- Bconws(com);
- Bconout(2, ' ');
- if(optarg != (char *)NULL)
- {
- Bconws(optarg);
- Bconout(2, ' ');
- }
- Bconws(args); CRLF;
- if(optarg != (char *)NULL)
- {
- buf[(BSIZE/2)] = strlen(optarg) + strlen(args) + 1;
- (void)strcat(strcat(strcpy(&buf[(BSIZE/2+1)], optarg), " "),
- args);
- return (int)Pexec(0, com, &buf[(BSIZE/2)], env);
- }
- else
- {
- buf[0] = strlen(args);
- (void) strcpy(&buf[1], args);
- return (int)Pexec(0, com, buf, env);
- }
- }
-
- int main()
- {
- register char *com, *args, *line;
- register int i, status;
-
- /* Set Up Stderr */
- Fforce(2,(int)Fdup(1));
-
- stat = (STAT *)Fgetdta();
-
- cd(HOME);
- while(1)
- {
- PROMPT;
- buf[0] = 127;
- if(rhandle > (-3))
- read_at(buf);
- else
- {
- Cconrs(buf);
- Bconout(2, '\n');
- }
- if(buf[1] == 0)
- continue;
-
- buf[(buf[1]+2)] = '\0';
- line = &buf[2];
- com = line;
-
- /* pick up argv[0] */
- while((*line != '\0') && (!iswhite(*line)))
- line++;
-
- if(*line != '\0')
- {
- *line++ = '\0';
- }
- args = line;
-
- status = 0;
- if((i = find_builtin(com)) >= 0)
- status = (*(builtin[i].routine))(args);
- else if ((i = find_alias(com)) >= 0)
- status = do_command(alias[i].adef, alias[i].optarg,
- args);
- else if ((line = find_ext(com)) != (char *)NULL)
- status = do_command(line, (char *)NULL, args);
- else
- {
- Bconws(com);Bconws(" not found\r\n");
- continue;
- }
- if(status != 0)
- {
- PRINTI(status); CRLF;
- }
-
- }
- return 0;
- }
-
- /* -eof- */
-